<?php
namespace App\Blocks;

use App\Models\AmapCityCode;
use App\Models\Carts;
use App\Models\Goods;
use App\Models\OrderAddress;
use App\Models\OrderInfos;
use App\Models\Orders;
use App\Models\UserAddress;
use DB;
class OrderBlock
{

    public function updateCart($uid, $gid, $buyNum){
        $cartModel = new Carts();
        $goodsModel = new Goods();
        $cart = DB::table($cartModel->getTable())
            ->where('u_id', $uid)
            ->where('g_id', $gid)
            ->first();

        if($buyNum <= 0){
            if($cart) {
                //如果购买数量为0，则删除
                return DB::table($cartModel->getTable())
                    ->where('u_id', $uid)
                    ->where('g_id', $gid)
                    ->delete();
            }else{
                return true;
            }
        }

        $goods = DB::table($goodsModel->getTable())
            ->where('id', $gid)
            ->whereNull('deleted_at')
            ->where('status', 1)
            ->first();

        if(!$goods){
            //商品已下架或被删除
            return -1;
        }

        if($goods->stock_num < $buyNum){
            //库存不足
            return -2;
        }

        if($cart){
            if(DB::table($cartModel->getTable())
                ->where('u_id', $uid)
                ->where('g_id', $gid)
                ->update([
                    'buy_num' => $buyNum
                ]) === false){
                return false;
            }else{
                return true;
            }
        }else{
            return DB::table($cartModel->getTable())
                ->insert([
                    'buy_num'       => $buyNum,
                    'u_id'          => $uid,
                    'g_id'          => $gid,
                    'now_price'     => $goods->now_price
                ]);
        }
    }


    public function cart($uid){
        $cartModel = new Carts();
        $goodsModel = new Goods();

        $perfix = env('DB_PREFIX');

        return DB::table($cartModel->getTable() . ' as ct')
            ->select(
                'g.id',
                'g.c_id',
                'g.b_id',
                'g.show_title',
                'g.name',
                'g.small_image',
                'g.producing_area',
                'g.unit',
                'g.stock_num',
                'g.slogan',
                'g.illustrate',
                DB::raw("convert(out_price/100, decimal(15,2)) as out_price"),
                DB::raw("convert({$perfix}g.now_price/100, decimal(15,2)) as now_price"),
                'g.status',
                'g.updated_at',
                DB::raw("if({$perfix}ct.buy_num,{$perfix}ct.buy_num,0) as buy_num")
            )
            ->leftJoin($goodsModel->getTable() . ' as g', 'g.id', '=', 'ct.g_id')
            ->whereNull('g.deleted_at')
            ->where('ct.u_id', $uid)
            ->orderBy('ct.updated_at')
            ->get();
    }

    public function createOrder($uid, $gids, $isBuyNow=0){
        $orderModel = new Orders();
        $orderGoodsModel = new OrderInfos();
        $userAddressModel = new UserAddress();
        $orderAddressModel = new OrderAddress();


        //商品总价
        $goodsPrice = 0;
        //实际需要支付
        $pay = 0;

        $goodsBlock = new GoodsBlock();
        if($isBuyNow){
            //如果是立即购买，购买数量为1
            $goods = $goodsBlock->getGoods($uid, ['id' => $gids], 1, count($gids));
            foreach ($goods as $g){
                $g->buy_num = 1;
                $price = bcmul($g->now_price, $g->buy_numç,2) * 100;
                $goodsPrice += $price;
                $pay += $price;
            }
        }else {
            $goods = $goodsBlock->getGoods($uid, ['id' => $gids], 1, count($gids));
            foreach ($goods as $g){
                $price = bcmul($g->now_price, $g->buy_num,2)  * 100;
                $goodsPrice += $price;
                $pay += $price;
            }
        }

        //运费
        $freight = 0;
        //服务费
        $serviceCharge = 0;

        try{
            DB::beginTransaction();
            $orderId = DB::table($orderModel->getTable())
                ->insertGetId([
                    'order_num' => date('YmdHis', time()) . getSalt(4, 1),
                    'u_id' => $uid,
                    'service_charge' => $serviceCharge,
                    'freight' => $freight,
                    'g_total_price' => $goodsPrice,
                    'pay_total' => $pay,
                    'created_at' => date('Y-m-d H:i:s', time()),
                    'status' => 0
                ]);

            if(!$orderId){
                return false;
            }

            $orderGoods = [];
            foreach ($goods as $g){
                $orderGoods[] = [
                    'o_id' => $orderId,
                    'g_id' => $g->id,
                    'c_id' => $g->c_id,
                    'b_id' => $g->b_id,
                    'b_name' => $g->b_name,
                    'small_image' => $g->small_image,
                    'show_title' => $g->show_title,
                    'name'  => $g->name,
                    'producing_area' => $g->producing_area,
                    'unit' => $g->unit,
                    'now_price' => $g->now_price * 100,
                    'buy_num' => $g->buy_num,
                    'created_at' => date('Y-m-d H:i:s', time())
                ];
            }

            if(
                !DB::table($orderGoodsModel->getTable())
                ->insert($orderGoods)
            ){
                DB::rollBack();
                return false;
            }

            $userAddress = DB::table($userAddressModel->getTable())
                ->where('u_id', $uid)
                ->where('useing', 1)
                ->whereNull('deleted_at')
                ->first();
            if($userAddress){
                if(
                    !DB::table($orderAddressModel->getTable())
                        ->insert([
                            'o_id'          => $orderId,
                            'a_id'          => $userAddress->id,
                            'name'          => $userAddress->name,
                            'mobile'        => $userAddress->mobile,
                            'province'      => $userAddress->province,
                            'city'          => $userAddress->city,
                            'district'      => $userAddress->district,
                            'address'       => $userAddress->address,
                        ])
                ){
                    DB::rollBack();
                    return false;
                }
            }

            DB::commit();
            return $orderId;
        }catch (\Exception $exception){
            DB::rollBack();
            \Log::error($exception);
            return false;
        }
    }

    public function getOrderDetail($orderId){
        $orderGoodsModel = new OrderInfos();

        $sql = $this->_getOrderSql(['order_id' => $orderId]);
        $order = $sql->first();

        $orderGoods = DB::table($orderGoodsModel->getTable())
            ->select(
                'id',
                'o_id',
                'g_id',
                'c_id',
                'b_id',
                'b_name',
                'show_title',
                'small_image',
                'name',
                'producing_area',
                'unit',
                DB::raw("convert(now_price/100, decimal(15,2)) as now_price"),
                'buy_num',
                'created_at',
                'updated_at',
                's_id'
            )
            ->where('o_id', $orderId)
            ->get();

        if($order){
            $order->goods = $orderGoods;
        }

        return $order;

    }

    public function _getOrderSql($search){
        $orderModel = new Orders();
        $orderAddressModel = new OrderAddress();
        $districtModel = new AmapCityCode();

        $sql = DB::table($orderModel->getTable() . ' as o')
            ->select(
                'o.id',
                'o.u_id',
                'o.order_num',
                'o.service_charge',
                'o.freight',
                DB::raw("convert(g_total_price/100, decimal(15,2)) as g_total_price"),
                DB::raw("convert(pay_total/100, decimal(15,2)) as pay_total"),
                'o.status',
                'o.created_at',
                'o.pay_time',
                'oa.a_id',
                'oa.name',
                'oa.mobile',
                'oa.address',
                'dp.name as province',
                'dc.name as city',
                'dd.name as district'
            )
            ->leftJoin($orderAddressModel->getTable() . ' as oa', 'oa.o_id', '=', 'o.id')
            ->leftJoin($districtModel->getTable() . ' as dp', 'dp.id', '=', 'oa.province')
            ->leftJoin($districtModel->getTable() . ' as dc', 'dc.id', '=', 'oa.city')
            ->leftJoin($districtModel->getTable() . ' as dd', 'dd.id', '=', 'oa.district');

        if(isset($search['order_id'])) {
            $sql->where('o.id', $search['order_id']);
        }

        if(isset($search['user_id'])) {
            $sql->where('o.u_id', $search['user_id']);
        }

        if(isset($search['status'])) {
            $sql->where('o.status', $search['status']);
        }

        return $sql;
    }

    public function getOrder($search=[], $page=1, $pageSize=20){
        $orderGoodsModel = new OrderInfos();
        $sql = $this->_getOrderSql($search);

        $order = $sql->orderBy('updated_at', 'desc')
            ->skip(($page - 1) * $pageSize)->take($pageSize)
            ->get();

        $orderIds = [];
        foreach ($order as $o){
            $orderIds[] = $o->id;
        }

        $orderGoods = DB::table($orderGoodsModel->getTable())
            ->select(
                'id',
                'o_id',
                'g_id',
                'c_id',
                'b_id',
                'b_name',
                'show_title',
                'small_image',
                'name',
                'producing_area',
                'unit',
                DB::raw("convert(now_price/100, decimal(15,2)) as now_price"),
                'buy_num',
                'created_at',
                'updated_at',
                's_id'
            )
            ->whereIn('o_id', $orderIds)
            ->get();

        foreach ($order as $o){
            $o->goods = [];
            foreach ($orderGoods as $og) {
                if ($o->id === $og->o_id){
                    $o->goods[] = $og;
                }
            }
        }

        return $order;
    }
}